import 'dart:async';
import 'dart:collection';
import 'package:flutter/foundation.dart';

/// 缓存性能监控器
/// 跟踪和分析缓存性能指标
class CachePerformanceMonitor {
  static CachePerformanceMonitor? _instance;
  static CachePerformanceMonitor get instance =>
      _instance ??= CachePerformanceMonitor._();

  CachePerformanceMonitor._();

  // 性能指标存储
  final Map<String, CacheMetrics> _urlMetrics = {};
  final LinkedHashMap<String, PerformanceEvent> _recentEvents = LinkedHashMap();

  Timer? _reportTimer;
  bool _isInitialized = false;

  // 配置参数
  static const int maxRecentEvents = 100;
  static const Duration reportInterval = Duration(minutes: 1);

  /// 初始化性能监控器
  void initialize() {
    if (_isInitialized) return;

    _startPerformanceReporting();
    _isInitialized = true;
    debugPrint('CachePerformanceMonitor: 初始化完成');
  }

  /// 记录缓存开始事件
  void recordCacheStart(String url) {
    final metrics = _getOrCreateMetrics(url);
    metrics.startTime = DateTime.now();
    metrics.totalAttempts++;

    _addEvent(PerformanceEvent(
      type: EventType.cacheStart,
      url: url,
      timestamp: DateTime.now(),
    ));

    debugPrint('CachePerformanceMonitor: 缓存开始 - $url');
  }

  /// 记录缓存进度更新
  void recordProgressUpdate(String url, double progress) {
    final metrics = _getOrCreateMetrics(url);
    metrics.lastProgress = progress;
    metrics.lastProgressUpdate = DateTime.now();

    // 计算下载速度（简单估算）
    if (metrics.startTime != null && progress > 0) {
      final elapsed = DateTime.now().difference(metrics.startTime!);
      metrics.estimatedSpeed = progress / elapsed.inSeconds;
    }

    _addEvent(PerformanceEvent(
      type: EventType.progressUpdate,
      url: url,
      timestamp: DateTime.now(),
      data: {'progress': progress},
    ));
  }

  /// 记录缓存完成事件
  void recordCacheComplete(String url) {
    final metrics = _getOrCreateMetrics(url);
    metrics.endTime = DateTime.now();
    metrics.successCount++;

    if (metrics.startTime != null) {
      metrics.totalDuration = metrics.endTime!.difference(metrics.startTime!);
    }

    _addEvent(PerformanceEvent(
      type: EventType.cacheComplete,
      url: url,
      timestamp: DateTime.now(),
      data: {'duration': metrics.totalDuration?.inMilliseconds},
    ));

    debugPrint(
        'CachePerformanceMonitor: 缓存完成 - $url (耗时: ${metrics.totalDuration?.inSeconds}秒)');
  }

  /// 记录缓存失败事件
  void recordCacheFailure(String url, String error) {
    final metrics = _getOrCreateMetrics(url);
    metrics.endTime = DateTime.now();
    metrics.errorCount++;
    metrics.lastError = error;

    if (metrics.startTime != null) {
      metrics.totalDuration = metrics.endTime!.difference(metrics.startTime!);
    }

    _addEvent(PerformanceEvent(
      type: EventType.cacheFailure,
      url: url,
      timestamp: DateTime.now(),
      data: {'error': error, 'duration': metrics.totalDuration?.inMilliseconds},
    ));

    debugPrint('CachePerformanceMonitor: 缓存失败 - $url: $error');
  }

  /// 记录内存使用情况
  void recordMemoryUsage(int totalListeners, int cacheStates) {
    _addEvent(PerformanceEvent(
      type: EventType.memoryUsage,
      url: 'system',
      timestamp: DateTime.now(),
      data: {
        'totalListeners': totalListeners,
        'cacheStates': cacheStates,
      },
    ));
  }

  /// 记录网络状态变化
  void recordNetworkChange(String from, String to) {
    _addEvent(PerformanceEvent(
      type: EventType.networkChange,
      url: 'system',
      timestamp: DateTime.now(),
      data: {'from': from, 'to': to},
    ));
  }

  /// 获取或创建指标对象
  CacheMetrics _getOrCreateMetrics(String url) {
    return _urlMetrics.putIfAbsent(url, () => CacheMetrics(url: url));
  }

  /// 添加性能事件
  void _addEvent(PerformanceEvent event) {
    // 生成事件ID
    final eventId =
        '${event.timestamp.millisecondsSinceEpoch}_${event.type.name}_${event.url.hashCode}';

    _recentEvents[eventId] = event;

    // 保持最近事件数量限制
    while (_recentEvents.length > maxRecentEvents) {
      _recentEvents.remove(_recentEvents.keys.first);
    }
  }

  /// 启动性能报告定时器
  void _startPerformanceReporting() {
    _reportTimer = Timer.periodic(reportInterval, (_) {
      _generatePerformanceReport();
    });
  }

  /// 生成性能报告
  void _generatePerformanceReport() {
    final report = getPerformanceReport();
    debugPrint('CachePerformanceMonitor: 性能报告\n${_formatReport(report)}');
  }

  /// 格式化报告
  String _formatReport(Map<String, dynamic> report) {
    final buffer = StringBuffer();
    buffer.writeln('=== 缓存性能报告 ===');
    buffer.writeln('总缓存任务: ${report['totalUrls']}');
    buffer.writeln(
        '成功率: ${(report['overallSuccessRate'] * 100).toStringAsFixed(1)}%');
    buffer.writeln(
        '平均耗时: ${report['averageDuration']?.toStringAsFixed(1) ?? 'N/A'}秒');
    buffer.writeln('总错误数: ${report['totalErrors']}');
    buffer.writeln('最近事件数: ${report['recentEventCount']}');

    final topErrors = report['topErrors'] as List<MapEntry<String, int>>;
    if (topErrors.isNotEmpty) {
      buffer.writeln('主要错误:');
      for (final error in topErrors.take(3)) {
        buffer.writeln('  - ${error.key}: ${error.value}次');
      }
    }

    return buffer.toString();
  }

  /// 获取指定URL的性能指标
  CacheMetrics? getUrlMetrics(String url) {
    return _urlMetrics[url];
  }

  /// 获取所有URL的性能指标
  List<CacheMetrics> getAllMetrics() {
    return _urlMetrics.values.toList();
  }

  /// 获取最近的性能事件
  List<PerformanceEvent> getRecentEvents({int? limit}) {
    final events = _recentEvents.values.toList();
    events.sort((a, b) => b.timestamp.compareTo(a.timestamp));

    if (limit != null && limit < events.length) {
      return events.take(limit).toList();
    }

    return events;
  }

  /// 获取综合性能报告
  Map<String, dynamic> getPerformanceReport() {
    final allMetrics = getAllMetrics();

    if (allMetrics.isEmpty) {
      return {
        'totalUrls': 0,
        'overallSuccessRate': 0.0,
        'averageDuration': null,
        'totalErrors': 0,
        'recentEventCount': _recentEvents.length,
        'topErrors': <MapEntry<String, int>>[],
      };
    }

    final totalAttempts =
        allMetrics.fold<int>(0, (sum, m) => sum + m.totalAttempts);
    final totalSuccess =
        allMetrics.fold<int>(0, (sum, m) => sum + m.successCount);
    final totalErrors = allMetrics.fold<int>(0, (sum, m) => sum + m.errorCount);

    final durationsInSeconds = allMetrics
        .where((m) => m.totalDuration != null)
        .map((m) => m.totalDuration!.inSeconds)
        .toList();

    final averageDuration = durationsInSeconds.isNotEmpty
        ? durationsInSeconds.reduce((a, b) => a + b) / durationsInSeconds.length
        : null;

    // 统计错误类型
    final errorCounts = <String, int>{};
    for (final metrics in allMetrics) {
      if (metrics.lastError != null) {
        errorCounts[metrics.lastError!] =
            (errorCounts[metrics.lastError!] ?? 0) + 1;
      }
    }

    final topErrors = errorCounts.entries.toList()
      ..sort((a, b) => b.value.compareTo(a.value));

    return {
      'totalUrls': allMetrics.length,
      'overallSuccessRate':
          totalAttempts > 0 ? totalSuccess / totalAttempts : 0.0,
      'averageDuration': averageDuration,
      'totalErrors': totalErrors,
      'recentEventCount': _recentEvents.length,
      'topErrors': topErrors,
    };
  }

  /// 清理指定URL的性能数据
  void clearUrlMetrics(String url) {
    _urlMetrics.remove(url);
    debugPrint('CachePerformanceMonitor: 清理URL性能数据 - $url');
  }

  /// 清理所有性能数据
  void clearAllMetrics() {
    _urlMetrics.clear();
    _recentEvents.clear();
    debugPrint('CachePerformanceMonitor: 清理所有性能数据');
  }

  /// 释放资源
  void dispose() {
    if (!_isInitialized) return;

    _reportTimer?.cancel();
    _reportTimer = null;

    _urlMetrics.clear();
    _recentEvents.clear();

    _isInitialized = false;
    debugPrint('CachePerformanceMonitor: 资源释放完成');
  }
}

/// 缓存性能指标
class CacheMetrics {
  final String url;
  DateTime? startTime;
  DateTime? endTime;
  DateTime? lastProgressUpdate;
  double lastProgress = 0.0;
  double estimatedSpeed = 0.0; // 进度/秒
  Duration? totalDuration;
  int totalAttempts = 0;
  int successCount = 0;
  int errorCount = 0;
  String? lastError;

  CacheMetrics({required this.url});

  double get successRate =>
      totalAttempts > 0 ? successCount / totalAttempts : 0.0;
  bool get isActive => startTime != null && endTime == null;

  @override
  String toString() =>
      'CacheMetrics(url: $url, attempts: $totalAttempts, success: $successCount, errors: $errorCount, successRate: ${(successRate * 100).toStringAsFixed(1)}%)';
}

/// 性能事件
class PerformanceEvent {
  final EventType type;
  final String url;
  final DateTime timestamp;
  final Map<String, dynamic>? data;

  const PerformanceEvent({
    required this.type,
    required this.url,
    required this.timestamp,
    this.data,
  });

  @override
  String toString() =>
      'PerformanceEvent(type: $type, url: $url, timestamp: $timestamp, data: $data)';
}

/// 事件类型枚举
enum EventType {
  cacheStart,
  progressUpdate,
  cacheComplete,
  cacheFailure,
  memoryUsage,
  networkChange,
}
